/*
 * Copyright (C) 2010-2011 Enrique Lara (enrique.posix2.lara@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package app.timetogo;

import android.app.Activity;
import android.app.AlertDialog;

import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;

import android.database.Cursor;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import android.net.Uri;

import android.os.Bundle;

import android.view.ContextMenu;

import android.view.ContextMenu.ContextMenuInfo;

import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

import android.view.View.OnClickListener;

import android.view.ViewGroup;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;

import app.timetogo.model.Alarm;
import app.timetogo.model.App;
import app.timetogo.model.Stop;

import app.timetogo.provider.Projections;
import app.timetogo.provider.Tables.Alarms;

import app.timetogo.util.Constants;
import app.timetogo.util.Log;

import trs.wmata.TrainAgency;

/*
 * Consider "n" tabs All/Trains/Buses/... based on Alarm records.
 * Alarm/Matcher - Headsign vs. Final destination.
 * - If capturing final destination, assert station/line direction is valid for route...
 * - If capturing direction/headsign, check if headsign is in same direction as that of alarm.
 *
 *  XXX consdier Vechicles matches  = agency.getMatches(Criteria);
 */
public class AllAlarms extends Activity implements OnItemClickListener {
    private static final String TAG = "AllAlarms";
    public static final int MENU_ITEM_EDIT = Menu.FIRST;
    public static final int MENU_ITEM_DELETE = Menu.FIRST + 1;
    public static final int MENU_ITEM_START_NOW = Menu.FIRST + 2;
    public static final int MENU_ITEM_INSERT = Menu.FIRST + 3;
    public static final int MENU_ITEM_SETTING = Menu.FIRST + 4;
    public static final int MENU_ITEM_VIEW = Menu.FIRST + 5;
    public static final int MENU_ITEM_ALL_TRAINS = Menu.FIRST + 6;
    public static final int MENU_ITEM_ALL_BUSES = Menu.FIRST + 7;
    private static final int MENU_ITEM_ENABLE = Menu.FIRST + 8;
    private static final int MENU_ITEM_DISABLE = Menu.FIRST + 9;
    private static final int MENU_ITEM_ABOUT = Menu.FIRST + 10;
    private ListView allAllarms = null;

    private static class AlarmAdapter extends CursorAdapter {
        private final Bitmap enabledBmp;

        public AlarmAdapter(final Context context, final Cursor c) {
            super(context, c);

            enabledBmp = BitmapFactory.decodeResource(context.getResources(), android.R.drawable.presence_online);
        }

        @Override
        public void bindView(final View view, final Context context, final Cursor cursor) {
            final Alarm a = App.loadAlarm(cursor, context);

            final int lineImageId = a.getRoute().getImageId();

            if (a.isEnabled()) {
                final ImageView icon = (ImageView) view.findViewById(R.id.alarm_icon);
                icon.setImageBitmap(enabledBmp);
            }

            Android.cptxt(view, R.id.alarm_time, a.getTimeStr());
            Android.cptxt(view, R.id.alarm_repeat, a.getRepeatStr());
            Android.cptxt(view, R.id.alarm_station, a.getStopName());
            Android.cptxt(view, R.id.alarm_label, a.getLabel());

            final ImageView line = (ImageView) view.findViewById(R.id.alarm_line);
            line.setImageResource(lineImageId);
        }

        @Override
        public View newView(final Context context, final Cursor cursor, final ViewGroup parent) {
            final View view = LayoutInflater.from(context).inflate(R.layout.list_item_alarm, null);

            return view;
        }
    }

    @Override
    public final void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);

        // If no data was given in the intent (because we were started
        // as a MAIN activity), then use our default content provider.
        final Intent intent = getIntent();

        if (intent.getData() == null) {
            intent.setData(Alarms.CONTENT_URI);
        }

        // Perform a managed query. The Activity will handle closing and requerying the cursor
        // when needed.
        final String where = null; //Alarms.AGENCY_ID + " = ?"; //XXX 86
        final String[] whereArgs = null; //new String[] { Integer.toString(getAlarmType()) };
        final Cursor cursor = managedQuery(getIntent().getData(), Projections.AlarmsAll.PROJECTION, where, whereArgs, Alarms.DEFAULT_SORT_ORDER);

        final AlarmAdapter adapter = new AlarmAdapter(this, cursor);
        setContentView(R.layout.all);
        allAllarms = (ListView) findViewById(R.id.all_alarms);
        allAllarms.setAdapter(adapter);
        allAllarms.setOnCreateContextMenuListener(this);
        allAllarms.setOnItemClickListener(this);

        final Button b = (Button) findViewById(R.id.add_alarm);
        b.setOnClickListener(new OnClickListener() {
                public void onClick(final View v) {
                    gotoInsert();
                }
            });
    }

    @Override
    public final boolean onCreateOptionsMenu(final Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(0, MENU_ITEM_ABOUT, 0, R.string.about).setShortcut('6', 'i').setIcon(android.R.drawable.ic_menu_info_details);
        menu.add(0, MENU_ITEM_INSERT, 1, R.string.add_alarm).setShortcut('3', 'a').setIcon(android.R.drawable.ic_menu_add);
        menu.add(0, MENU_ITEM_SETTING, 2, R.string.settings).setShortcut('9', 's').setIcon(android.R.drawable.ic_menu_preferences);

        return true;
    }

    @Override
    public final boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
            case MENU_ITEM_INSERT:
                gotoInsert();

                return true;

            case MENU_ITEM_SETTING:
                startActivity(new Intent(Constants.ACTION_SETTINGS));

                return true;

            case MENU_ITEM_ABOUT:
                startActivity(new Intent(Constants.ACTION_ABOUT));

                return true;

            case MENU_ITEM_ALL_TRAINS:
                startActivity(new Intent(Constants.ACTION_ALL_TRAINS));

                return true;

            case MENU_ITEM_ALL_BUSES:
                startActivity(new Intent(Constants.ACTION_ALL_BUSES));

                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void gotoInsert() {
        //XXX select type ie, agency, then proceed to insert with some data.
        final Intent intent = new Intent(Constants.ACTION_INSERT, getIntent().getData());
        intent.putExtra(Alarms.AGENCY_ID, TrainAgency.WMATA_TRAIN_AGENCY_ID); //FIXME drop-down
        startActivity(intent);
    }

    @Override
    public final void onCreateContextMenu(final ContextMenu menu, final View view, final ContextMenuInfo menuInfo) {
        AdapterView.AdapterContextMenuInfo info;

        try {
            info = (AdapterView.AdapterContextMenuInfo) menuInfo;
        } catch (final ClassCastException e) {
            Log.e(TAG, "bad menuInfo", e);

            return;
        }

        final Cursor cursor = (Cursor) allAllarms.getAdapter().getItem(info.position);

        if (cursor == null) {
            // For some reason the requested item isn't available, do nothing
            return;
        }

        // Setup the menu header
        String label = cursor.getString(Projections.AlarmsAll.LABEL);

        if (label == null) {
            final int agencyId = cursor.getInt(Projections.AlarmsAll.AGENCY_ID);
            final String stopCode = cursor.getString(Projections.AlarmsAll.STOP);
            final Stop station = App.getAgency(agencyId, this).getStopByCode(stopCode);
            label = (station != null) ? station.getName() : stopCode;
        }

        menu.setHeaderTitle(label);
        menu.add(0, MENU_ITEM_VIEW, 0, R.string.view_alarm);
        menu.add(0, MENU_ITEM_START_NOW, 0, R.string.start_polling_now);
        /* XXX uncomment once figure out how to refresh listview.
        if(a.isEnabled()) {
        menu.add(0, MENU_ITEM_DISABLE, 0, R.string.alarm_disable);
        } else {
        menu.add(0, MENU_ITEM_ENABLE, 0, R.string.alarm_enable);
        }
         */
        menu.add(0, MENU_ITEM_EDIT, 0, R.string.edit_alarm);
        menu.add(0, MENU_ITEM_DELETE, 0, R.string.delete_alarm);
    }

    @Override
    public final boolean onContextItemSelected(final MenuItem item) {
        AdapterView.AdapterContextMenuInfo info;

        try {
            info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        } catch (final ClassCastException e) {
            Log.e(TAG, "bad menuInfo", e);

            return false;
        }

        final Uri alarmUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
        final Alarm a = App.loadAlarm(alarmUri, this);

        switch (item.getItemId()) {
            case MENU_ITEM_START_NOW:
                return a.startPollingNow();

            case MENU_ITEM_EDIT:
                return a.gotoEdit();

            case MENU_ITEM_DELETE: {
                final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage(R.string.confirm_delete_alarm).setTitle(R.string.delete_alarm).setCancelable(false).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                        public void onClick(final DialogInterface dialog, final int id) {
                            a.delete();
                            dialog.dismiss();
                        }
                    }).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                        public void onClick(final DialogInterface dialog, final int id) {
                            dialog.dismiss();
                        }
                    });
                builder.show();

                return true;
            }

            case MENU_ITEM_VIEW:
                return a.gotoView();

            case MENU_ITEM_ENABLE: {
                a.setEnabled(true);

                return a.update();
            }

            case MENU_ITEM_DISABLE: {
                a.setEnabled(false);

                return a.update();
            }

            default:
                return false;
        }
    }

    public final void onItemClick(final AdapterView<?> l, final View v, final int position, final long id) {
//	protected void onListItemClick(ListView l, View v, int position, long id) {
        final Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);

        final String action = getIntent().getAction();

        if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
            setResult(RESULT_OK, new Intent().setData(uri));
        } else {
            Alarm.gotoEdit(uri, this);
        }
    }
}
